/*
 * app_cli_cmd.c
 *
 *  Created on: 2023年7月4日
 *      Author: zlw
 */

#include "app_cli_cmd.h"
#include "app_cli_config.h"
#include "bsp_system.h"
#include "em_gpio.h"
#include "app_log.h"
#include "bsp_init.h"
#include "bsp_usart.h"
#include "bsp_gpio.h"
#include "btl_reset_info.h"
#include "app_multislot.h"
#include "app_cli.h"
#include "softwareMultiTimer.h"
#include "app_api.h"
#include "bsp_rtc.h"
#include "em_emu.h"
#include "em_cmu.h"
#include "sl_device_init_lfxo.h"
#include "device.h"
#include "bsp_timer.h"
#include "device_type.h"
#include "app_filetransport_api.h"
#include "mac_transmitter.h"
#include "git_version.h"
#include "app_broadcast_retry.h"
#ifdef HUB_DEVICE
#include "app_hub_api.h"
#include "device_rfmid.h"
#include "net_aseq.h"
#include "net_register.h"
#endif
#include "device_nvm.h"
#include "bsp_nvm.h"
#include "net_packet.h"
#include "mac_packetHandle.h"
#include "device_partition.h"
#include "bsp_sha.h"
#include "bsp_wdog.h"

#ifdef HUB_DEVICE
static uint8_t sounder_bseq = 1;
static uint8_t keypad_bseq = 1;
static uint8_t switch_bseq = 1;

#else

#endif

static MultiTimer rawRssiTimer;
static uint16_t testChannel = 6;

/********************************************************************/

static void help(ds_cli_command_arg_t *arguments);

static void get_mac_info(ds_cli_command_arg_t *arguments)
{
  (void)arguments;
  uint8_t macAddr[8] = {0x00};
  getMacAddr(macAddr);
  APP_PRINTF("mac : ");
  for(uint8_t i=0;i<8;i++){
      APP_PRINTF("%02x ", macAddr[i]);
  }
  APP_PRINTF("\r\n");
}

static void set_tx_power(ds_cli_command_arg_t *arguments)
{
  RAIL_TxPower_t power = ds_cli_get_argument_int16(arguments, 0);

  bsp_set_rf_idle(RAIL_IDLE_ABORT, true);

  if(DS_STATUS_OK != bsp_rf_set_tx_power_bdm(power)) {
      APP_PRINTF("set tx power failed \r\n");
  }
  else {
      power = bsp_rf_get_tx_power_bdm();
      setThisParam(RfTxPower, &power);
      APP_PRINTF("current tx power = %d \r\n", power);
  }
}

static void get_tx_power(ds_cli_command_arg_t *arguments)
{
  (void)arguments;
  APP_PRINTF("txPower = %d \r\n", bsp_rf_get_tx_power_bdm());
}

static void rx(ds_cli_command_arg_t *arguments)
{
  bool enable = !!ds_cli_get_argument_uint8(arguments, 0);

  RAIL_RadioState_t currentState = bsp_get_rf_state();

  if ((enable && (currentState & RAIL_RF_STATE_RX))
      || (!enable && (currentState <= RAIL_RF_STATE_IDLE))) {
    // Do nothing since we're already in the right state
  } else if (enable) {
      bsp_rf_start_rx(testChannel, NULL);
  } else {
      bsp_set_rf_idle(RAIL_IDLE_ABORT, true);
  }
}

static void get_channel(ds_cli_command_arg_t *arguments)
{
  (void)arguments;

  APP_PRINTF("current channel = %d \r\n", testChannel);
}

static void set_channel(ds_cli_command_arg_t *arguments)
{
  uint16_t channel = ds_cli_get_argument_uint16(arguments, 0);

  testChannel = channel;
  APP_PRINTF("current channel = %d \r\n", testChannel);
}

static void start_tx_tone(ds_cli_command_arg_t *arguments)
{
  uint8_t enable = ds_cli_get_argument_uint8(arguments, 0);
  RAIL_StreamMode_t streamMode = ds_cli_get_argument_uint8(arguments, 1);
  uint8_t opt = ds_cli_get_argument_uint8(arguments, 2);
  RAIL_Status_t status;

  RAIL_TxOptions_t option = 0;
  if(opt)
    option = RAIL_TX_OPTION_ANTENNA1;
  else
    option = RAIL_TX_OPTION_ANTENNA0;
  APP_PRINTF("current channel = %d \r\n", testChannel);
  if(enable) {
      status = bsp_rf_start_tx_stream_alt(testChannel, streamMode, option);
  }
  else {
      status = bsp_rf_stop_tx_stream();
  }
  if(RAIL_STATUS_NO_ERROR != status) {
      DS_app_log_debug("%s tx tone failed\r\n", enable?"enable":"disable");
  }
  else {
      APP_PRINTF("%s tx tone success\r\n", enable?"enable":"disable");
  }
}

static void set_ctune(ds_cli_command_arg_t *arguments)
{
  uint32_t tune = ds_cli_get_argument_uint32(arguments, 0);

  bsp_set_rf_idle(RAIL_IDLE_ABORT, true);

  if (DS_STATUS_OK != bsp_rf_set_ctune(tune)) {
    DS_app_log_info("set ctune failed\r\n");
    return;
  }
  else {
      tune = bsp_rf_get_ctune();
      setThisParam(RfCtune, &tune);
      APP_PRINTF("current ctune = %ld\r\n", tune);
  }
}

static void get_ctune(ds_cli_command_arg_t *arguments)
{
  (void)arguments;
  APP_PRINTF("current ctune = %ld\r\n", bsp_rf_get_ctune());
}

static void set_lfxo_ctune(ds_cli_command_arg_t *arguments)
{
  uint8_t tune = ds_cli_get_argument_uint8(arguments, 0);

  CMU_LFXOInit_TypeDef lfxoInit = CMU_LFXOINIT_DEFAULT;

  lfxoInit.mode = cmuLfxoOscMode_Crystal;
  lfxoInit.capTune = tune;
  lfxoInit.timeout = cmuLfxoStartupDelay_4KCycles;

  CMU_LFXOInit(&lfxoInit);
  CMU_LFXOPrecisionSet(100);

  setThisParam(lfxoCtune, &tune);

  APP_PRINTF("current LFXO ctune = %d\r\n", tune);
}

static void antenna_config(ds_cli_command_arg_t *arguments)
{
  uint8_t ann = ds_cli_get_argument_uint8(arguments, 0);

  RAIL_AntennaConfig_t config = {
      .ant0PinEn = 1,
      .ant1PinEn = 1,
      .defaultPath = RAIL_ANTENNA_0,
      .reserved = 0,
      .ant0Port = gpioPortA,
      .ant0Pin = 3,
      .ant1Port = gpioPortA,
      .ant1Pin = 4

  };

  if(ann == 1) {
      config.defaultPath = RAIL_ANTENNA_1;
  }

  bsp_set_rf_idle(RAIL_IDLE_ABORT, true);
  uint8_t status = bsp_rf_config_antenna(&config);
  if(status != 0) {
      DS_app_log_info("antenna config fail \r\n");
  }
}

static void cli_cmd_get_raw_rssi_timer_handle_callback(MultiTimer* timer, void* userData)
{
  (void)userData;

  bsp_rf_start_rx(testChannel, NULL);
  int16_t rawRssi = bsp_rf_get_raw_rssi(true);
  APP_PRINTF("raw RSSI = %d dbm\r\n", rawRssi/4);
  softwareMultiTimerStart(EN_LP_HARD_TIMER_EM3_SYS_RTC, timer, 3277, cli_cmd_get_raw_rssi_timer_handle_callback,NULL,1);
}

static void get_raw_rssi(ds_cli_command_arg_t *arguments)
{
  uint8_t enable = ds_cli_get_argument_uint8(arguments, 0);

  if(enable) {
      softwareMultiTimerStart(EN_LP_HARD_TIMER_EM3_SYS_RTC, &rawRssiTimer, 3277, cli_cmd_get_raw_rssi_timer_handle_callback,NULL,1);
  } else {
      softwareMultiTimerStop(EN_LP_HARD_TIMER_EM3_SYS_RTC, &rawRssiTimer,0);
  }
}

static void reset(ds_cli_command_arg_t *arguments)
{
  (void)arguments;
  // Set reset reason to bootloader entry
  BootloaderResetCause_t* resetCause = (BootloaderResetCause_t*) (SRAM_BASE);
  resetCause->reason = BOOTLOADER_RESET_REASON_GO;
  resetCause->signature = BOOTLOADER_RESET_SIGNATURE_VALID;

  bsp_set_rf_idle(RAIL_IDLE_FORCE_SHUTDOWN_CLEAR_FLAGS,true);//软复位前 清空rail库标志
  NVIC_SystemReset();
}

static void enable_xmodem(ds_cli_command_arg_t *arguments)
{
  (void)arguments;
  // Set reset reason to bootloader entry
  BootloaderResetCause_t* resetCause = (BootloaderResetCause_t*) (SRAM_BASE);
  resetCause->reason = 0x020D;
  resetCause->signature = BOOTLOADER_RESET_SIGNATURE_VALID;

  NVIC_SystemReset();
}

static void clk_out_pin_config(ds_cli_command_arg_t *arguments)
{
  char type = *(ds_cli_get_argument_string(arguments, 0));
  char portChar = *(ds_cli_get_argument_string(arguments, 1));
  GPIO_Port_TypeDef port = portChar-'A';
  uint8_t pin = ds_cli_get_argument_uint8(arguments, 2);

  DS_app_log_info("type = %c  port = %c  pin = %d \r\n", type, portChar, pin);

  if(type == 'H') {
      if(port != 2 && port != 3){
        DS_app_log_info("port error !!! \r\n");
      }
      else{
          GPIO_DbgSWDIOEnable(false);
          GPIO_DbgSWDClkEnable(false);
        CMU_ClkOutPinConfig(0, cmuSelect_HFXO, 1, port, pin);
      }
  }
  else if(type == 'L') {
      if(port !=0 && port != 1){
        DS_app_log_info("port error !!! \r\n");
      }else{
          GPIO_DbgSWDIOEnable(false);
          GPIO_DbgSWDClkEnable(false);
        CMU_ClkOutPinConfig(2, cmuSelect_LFXO, 1, port, pin);
      }
  }
}

static void SN_set(ds_cli_command_arg_t *arguments)
{
  char *sn = ds_cli_get_argument_string(arguments, 0);

  if(strlen(sn) > 16) {
      DS_app_log_error("sn length error \r\n");
  }
  else {
      setThisParam(ENpbyKeyM, sn);
  }
}

static void SN_get(ds_cli_command_arg_t *arguments)
{
  (void)arguments;
  uint8_t sn[17] = {0};

  int ret = getThisParam(ENpbyKeyM, sn);
  if(ret == 0)
    DS_app_log_error("sn:%s\r\n",sn);
  else
    DS_app_log_error("sn get error \r\n");
}

static void soft_version_get(ds_cli_command_arg_t *arguments)
{
  (void)arguments;
  uint8_t version[3] = {0};

  int ret = getThisParam(ENpbySensorVer, version);
  if(ret == 0)
    DS_app_log_error("soft version:v%d.%d.%d \r\n",version[0], version[1], version[2]);
  else
    DS_app_log_error("soft version get error delay\r\n");
}

static void ResetNvm(ds_cli_command_arg_t *arguments)
{
  (void)arguments;
  NVM_ERR_E status;
  uint32_t pre_ticks = 0;
  uint32_t now_ticks = 0;
  uint32_t diff_ticks = 0;
#ifdef HUB_DEVICE
  unsigned char panid[PANID_LENGTH] = {'\0'};
  unsigned char systemid[3] = {'\0'};
#endif
  unsigned char sn[SN_LENGTH + 1] = {'\0'};
  int16_t txPowerDeciDbm = 0;
  uint32_t rf_ctune = 0;
  uint8_t lfxo_ctune = 0;

#ifdef HUB_DEVICE
  getThisParam(ENpbyPanId, panid);
#if(1) //TODO 主HUB SystemID 不删除
  getThisParam(ENpbySystemID, systemid);
#endif
#endif
  getThisParam(ENpbyKeyM, sn);
  getThisParam(RfTxPower, &txPowerDeciDbm);
  getThisParam(RfCtune, &rf_ctune);
  getThisParam(lfxoCtune, &lfxo_ctune);

  //DS_app_func_tm_in();
  status = DS_nvmReset();
  //DS_app_func_tm_end("cdc");
  DS_app_log_error("reset nvm %d \r\n",status);

#ifdef HUB_DEVICE
  setThisParam(ENpbyPanId, panid);
#if(1) //TODO 主HUB SystemID 不删除
  setThisParam(ENpbySystemID, systemid);
#endif
#endif
  setThisParam(ENpbyKeyM, sn);
  setThisParam(RfTxPower, &txPowerDeciDbm);
  setThisParam(RfCtune, &rf_ctune);
  setThisParam(lfxoCtune, &lfxo_ctune);

  pre_ticks = READ_SYS_RTC_COUNT();
  while(1){
      now_ticks = READ_SYS_RTC_COUNT();
      if(now_ticks >= pre_ticks){
          diff_ticks = now_ticks - pre_ticks;
      }else{
          diff_ticks = now_ticks - pre_ticks + 1 + 0xffffffffUL;
      }
      if(diff_ticks >= 655){ //延迟20ms，然后重启芯片
          break;
      }
  }
  BootloaderResetCause_t* resetCause = (BootloaderResetCause_t*) (SRAM_BASE);
  resetCause->reason = BOOTLOADER_RESET_REASON_RESETNVM;
  resetCause->signature = BOOTLOADER_RESET_SIGNATURE_VALID;
  NVIC_SystemReset();
}

static void FileLogEnable(ds_cli_command_arg_t *arguments)
{
  (void)arguments;
  uint8_t enable = ds_cli_get_argument_uint8(arguments, 0);
  set_api_log_enable(FILE_API_LOG, enable);
  get_api_log_enable(FILE_API_LOG, &file_log_enable);
  DS_app_log_error("file log %d\r\n",file_log_enable);
}

static void MACLogEnable(ds_cli_command_arg_t *arguments)
{
  (void)arguments;
  uint8_t enable = ds_cli_get_argument_uint8(arguments, 0);
  set_api_log_enable(MAC_API_LOG, enable);
  DS_app_log_error("mac log %d\r\n",get_mac_printf_log());
}

static void NetLogEnable(ds_cli_command_arg_t *arguments)
{
  (void)arguments;
  uint8_t enable = ds_cli_get_argument_uint8(arguments, 0);
  set_net_printf_log(enable, true);
  DS_app_log_error("net log %d\r\n",enable);
}

static void LogEnable(ds_cli_command_arg_t *arguments)
{
  (void)arguments;
  uint8_t log_enable[4] = {0x00};
  bool enable = false;

  log_enable[0] = ds_cli_get_argument_uint8(arguments, 0);
  log_enable[1] = ds_cli_get_argument_uint8(arguments, 1);
  log_enable[2] = ds_cli_get_argument_uint8(arguments, 2);
  log_enable[3] = ds_cli_get_argument_uint8(arguments, 3);
  set_api_log_enable_multiple_module(&log_enable[0],
                                     &log_enable[1],
                                     &log_enable[2],
                                     &log_enable[3]);

#ifdef HUB_DEVICE
  get_api_log_enable(HUB_API_LOG, &hub_log_enable);
  DS_app_log_error("hub log %d\r\n",hub_log_enable);
#endif
  get_api_log_enable(FILE_API_LOG, &file_log_enable);
  DS_app_log_error("file log %d\r\n",file_log_enable);

  DS_app_log_error("mac log %d\r\n",get_mac_printf_log());

  enable = ((log_enable[0] & (1 << 3)) >> 3) ? (true):(false);
  set_net_printf_log(enable, false);
  DS_app_log_error("net log %d\r\n",enable);
}
#ifdef RFM_DEVICE
static void led_blink(ds_cli_command_arg_t *arguments)
{
    uint8_t data[5] = {0x00};
    if(ds_cli_get_argument_count(arguments) != 5){
        DS_app_log_info("param count error\r\n");
        return ;
    }

    uint8_t i=0;
    for(i=0;i<5;i++)
      data[i] = ds_cli_get_argument_uint8(arguments, i);

    SM_led_start(data, CLI_TEST_BLINK);
}

static void get_battery(ds_cli_command_arg_t *arguments)
{
  (void)arguments;
  uint16_t battery =SM_battery_get();
  APP_PRINTF("battery = %d \r\n", battery);

#ifdef SM_OUTSOUND
  extern uint32_t get_adc_channel(uint8_t channel);
  battery =get_adc_channel(3)*3;
  APP_PRINTF("sun battery = %d \r\n", battery);
#endif
}

static void get_temperature(ds_cli_command_arg_t *arguments)
{
  (void)arguments;

  int8_t temperature = SM_tempDrv_get();

  APP_PRINTF("temperature = %d \r\n", temperature);
}


static void option_set(ds_cli_command_arg_t *arguments)
{
  uint8_t option[3] = {0x00};
  for(uint8_t i=0;i<3;i++)
    option[i] = ds_cli_get_argument_uint8(arguments, i);

  recv_option_key_value_handler(option);
}

static void operate_set(ds_cli_command_arg_t *arguments)
{
  uint8_t operate[3] = {0x00};
  for(uint8_t i=0;i<3;i++)
    operate[i] = ds_cli_get_argument_uint8(arguments, i);

  recv_operation_key_value_handler(operate);
}

static void qrf_set(ds_cli_command_arg_t *arguments)
{
  uint8_t qrf1 = ds_cli_get_argument_uint8(arguments, 0);
  uint8_t qrf2 = ds_cli_get_argument_uint8(arguments, 1);

  QRFH1_t qrfH1 = {0x00};
  QRFH2_t qrfH2 = {0x00};

  memcpy(&qrfH1, &qrf1, sizeof(QRFH1_t));
  memcpy(&qrfH2, &qrf2, sizeof(QRFH2_t));

  SM_device_QRF_state_Handle(qrfH1, qrfH2);
}


static void relay_status_set(ds_cli_command_arg_t *arguments)
{
#if defined(SM_RL) || defined(SM_WS) || defined(SM_SMART_PLUG)

#if defined(SM_RL) || defined(SM_WS)
  ds_gpio_t relay = {
      .port = gpioPortC,
      .pin = 6,
      .mode = gpioModePushPull,
      .initial = 0,
      .valid = 1,
  };
  ds_gpio_t blueLed = {
      .port = gpioPortC,
      .pin = 0,
      .mode = gpioModePushPull,
      .initial = 1,
      .valid = 0,
  };

#elif defined(SM_SMART_PLUG)
   ds_gpio_t relay = {
      .port = gpioPortA,
      .pin = 6,
      .mode = gpioModePushPull,
      .initial = 0,
      .valid = 1,
  };
   ds_gpio_t blueLed = {
       .port = gpioPortC,
       .pin = 2,
       .mode = gpioModePushPull,
       .initial = 0,
       .valid = 1,
   };

#endif
   uint8_t status = ds_cli_get_argument_uint8(arguments, 0);

   ds_gpio_init(&relay);
   ds_gpio_init(&blueLed);

   if(status) {
       ds_gpio_on(&relay);
       ds_gpio_on(&blueLed);
   }
   else {
       ds_gpio_off(&relay);
       ds_gpio_off(&blueLed);
   }
#else
   (void)arguments;
#endif
}

static void key_pad_led(ds_cli_command_arg_t *arguments)
{
#ifdef SM_KP
  uint8_t led = ds_cli_get_argument_uint8(arguments, 0);
  uint8_t state = ds_cli_get_argument_uint8(arguments, 1);

  switch(led){
    case 0:
      if(state) {
          keyPad_led_on(FAULT_ORANGE);
      } else {
          keyPad_led_off(FAULT_ORANGE);
      }
      break;
    case 1:
      if(state) {
          keyPad_led_on(ALERM_RED);
      } else {
          keyPad_led_off(ALERM_RED);
      }
      break;
    case 2:
      if(state) {
          keyPad_led_on(DEPLOY_GREEN);
      } else {
          keyPad_led_off(DEPLOY_GREEN);
      }
      break;
    case 3:
      if(state) {
          keyPad_led_on(DEPLOY_BLUE);
      } else {
          keyPad_led_off(DEPLOY_BLUE);
      }
      break;
    default:
      break;
  }
#else
  (void)arguments;
#endif
}

static void pir_enable(ds_cli_command_arg_t *arguments)
{
  uint8_t enable = ds_cli_get_argument_uint8(arguments, 0);
  uint16_t cnt = ds_cli_get_argument_uint16(arguments, 1);
  uint32_t times = ds_cli_get_argument_uint32(arguments, 2);
#ifdef SM_PIR
  extern void pir_interrupt_test_enable(uint8_t enable);
  pir_interrupt_test_enable(enable);
  extern void pirInvalidCntSet(uint16_t cnt);
  pirInvalidCntSet(cnt);
  extern void pirInvalidTimeSet(uint32_t times);
  pirInvalidTimeSet(times);
#else
  (void)enable;
  (void)cnt;
  (void)times;
#endif
}

static void SetRfmRfReq(ds_cli_command_arg_t *arguments)
{
  (void)arguments;
  unsigned char freq = 0;
  freq = ds_cli_get_argument_uint8(arguments, 0);

  if(freq != getDeviceRfFreq()){
      setDeviceRfFreq(freq);
      NVIC_SystemReset();
  }

}
#endif
#ifdef HUB_DEVICE
static void HubLogEnable(ds_cli_command_arg_t *arguments)
{
  (void)arguments;
  uint8_t enable = ds_cli_get_argument_uint8(arguments, 0);
  set_api_log_enable(HUB_API_LOG, enable);
  get_api_log_enable(HUB_API_LOG, &hub_log_enable);
  DS_app_log_error("hub log %d\r\n",hub_log_enable);
}

static void SN_register(ds_cli_command_arg_t *arguments)
{
  (void)arguments;
#ifdef HUB_DEVICE
  char *sn = ds_cli_get_argument_string(arguments, 0);
  unsigned char local_register = ENTER_LOCAL_MODE;
  unsigned char mac[MAC_ADDRESS_LENGTH] = {'\0'};
  unsigned char qr_key[16] = {'\0'};
  if(strlen(sn) > 16) {
      DS_app_log_error("sn length error \r\n");
  }else{
      setThisParam(ENbyRegisterSN, (unsigned char *)sn);
      setThisParam(ENbyLocalRegister, (unsigned char *)&local_register); //进入本地注册，清MAC QR_KEY
      setThisParam(ENbyRegisterMAC, (unsigned char *)mac);
      setThisParam(ENbyRegisterQrKey, (unsigned char *)qr_key);
      APP_PRINTF("set sn %s\r\n",sn);
  }
#else
  DS_app_log_error("RFM Not Supported\r\n");
#endif
}

static void RegisterMode(ds_cli_command_arg_t *arguments)
{
  (void)arguments;
#ifdef HUB_DEVICE
  uint8_t mode = ds_cli_get_argument_uint8(arguments, 0);

  unsigned char sn[SN_LENGTH + 1] = {'\0'};
  unsigned char mac[MAC_ADDRESS_LENGTH] = {'\0'};
  unsigned char qr_key[16] = {'\0'};


  setThisParam(ENbyRegisterSN, (unsigned char *)sn);
  setThisParam(ENbyRegisterMAC, (unsigned char *)mac);
  setThisParam(ENbyRegisterQrKey, (unsigned char *)qr_key);

  setThisParam(ENbyLocalRegister, (unsigned char *)&mode);

#else
  DS_app_log_error("RFM Not Supported\r\n");
#endif
}

static void IOenBC(ds_cli_command_arg_t *arguments)
{
  (void)arguments;
#ifdef HUB_DEVICE
  uint8_t bretry = ds_cli_get_argument_uint8(arguments, 0);
  uint8_t bitmask0 = ds_cli_get_argument_uint8(arguments, 1);
  uint8_t bitmask1 = ds_cli_get_argument_uint8(arguments, 2);
  uint8_t msg[18] = {0x00};
  msg[0] = bretry;
  msg[1] = 0x01;
  msg[2] = bitmask0;
  msg[3] = bitmask1;
  DS_hub_api_creat_rf_sync_broadcast_event(msg, 18);
#else
  DS_app_log_error("RFM Not Supported\r\n");
#endif
}

static void SounderBC(ds_cli_command_arg_t *arguments)
{
  (void)arguments;
#ifdef HUB_DEVICE
  uint8_t bretry = ds_cli_get_argument_uint8(arguments, 0);
  uint8_t bitmask0 = ds_cli_get_argument_uint8(arguments, 1);
  uint8_t bitmask1 = ds_cli_get_argument_uint8(arguments, 2);
  uint8_t opption = ds_cli_get_argument_uint8(arguments, 3);
  uint8_t i = 0;
  uint8_t msg[17] = {0x00};

  unsigned char bcast_busy = 0;
  getThisParam(ENbyBcastBusy, (unsigned char *)&bcast_busy);
  if(bcast_busy){
      DS_app_log_error("BcastBusy\r\n");
      return;
  }
  msg[0] = bretry;
  msg[1] = 0x02;
  msg[2] = sounder_bseq++;
  sounder_bseq = sounder_bseq & 0xff;
  if(sounder_bseq == 0){
      sounder_bseq = 2;
  }
  msg[3] = bitmask0;
  msg[4] = bitmask1;
  for(i = 0; i < 12; i++){
      msg[5+i] = opption;
  }
  DS_hub_api_creat_rf_sync_broadcast_event(msg, 17);
#else
  DS_app_log_error("RFM Not Supported\r\n");
#endif
}

static void KeypadBC(ds_cli_command_arg_t *arguments)
{
  (void)arguments;
#ifdef HUB_DEVICE
  uint8_t bretry = ds_cli_get_argument_uint8(arguments, 0);
  uint8_t bitmask = ds_cli_get_argument_uint8(arguments, 1);
  uint8_t opption = ds_cli_get_argument_uint8(arguments, 2);
  uint8_t i = 0;
  uint8_t msg[12] = {0x00};

  unsigned char bcast_busy = 0;
  getThisParam(ENbyBcastBusy, (unsigned char *)&bcast_busy);
  if(bcast_busy){
      DS_app_log_error("BcastBusy\r\n");
      return;
  }
  msg[0] = bretry;
  msg[1] = 0x03;
  msg[2] = keypad_bseq++;
  keypad_bseq = keypad_bseq & 0xff;
  if(keypad_bseq == 0){
      keypad_bseq = 2;
  }
  msg[3] = bitmask;
  for(i = 0; i < 8; i++){
      msg[4+i] = opption;
  }
  DS_hub_api_creat_rf_sync_broadcast_event(msg, 12);
#else
  DS_app_log_error("RFM Not Supported\r\n");
#endif
}

static void UpdatemeBC(ds_cli_command_arg_t *arguments)
{
  (void)arguments;
#ifdef HUB_DEVICE
  uint8_t bretry = ds_cli_get_argument_uint8(arguments, 0);
  uint8_t rfmid = ds_cli_get_argument_uint8(arguments, 1);
  uint8_t ctrl = ds_cli_get_argument_uint8(arguments, 2);
  unsigned char bcast_busy = 0;
  getThisParam(ENbyBcastBusy, (unsigned char *)&bcast_busy);
  if(bcast_busy){
      DS_app_log_error("BcastBusy\r\n");
      return;
  }
  uint8_t msg[5] = {0x00};
  int msg_len = 0;

  msg[msg_len++] = bretry;
  msg[msg_len++] = 0x08;
  msg[msg_len++] = 2;
  msg[msg_len++] = ctrl;
  msg[msg_len++] = rfmid;
  DS_hub_api_creat_rf_sync_broadcast_event(msg, msg_len);
#else
  DS_app_log_error("RFM Not Supported\r\n");
#endif
}

static void SwitchBC(ds_cli_command_arg_t *arguments)
{
  (void)arguments;
#ifdef HUB_DEVICE
  uint8_t bretry = ds_cli_get_argument_uint8(arguments, 0);
  uint8_t no = ds_cli_get_argument_uint8(arguments, 1);
  uint8_t option = ds_cli_get_argument_uint8(arguments, 2);

  unsigned char bcast_busy = 0;
  getThisParam(ENbyBcastBusy, (unsigned char *)&bcast_busy);
  if(bcast_busy){
      DS_app_log_error("BcastBusy\r\n");
      return;
  }

  uint8_t msg[6] = {0x00};
  int msg_len = 0;

  msg[msg_len++] = bretry;
  msg[msg_len++] = 0x04;
  msg[msg_len++] = switch_bseq++;
  switch_bseq = switch_bseq & 0xff;
  if(switch_bseq == 0){
      switch_bseq = 2;
  }
  msg[msg_len++] = 2;
  msg[msg_len++] = no;
  msg[msg_len++] = option;
  DS_hub_api_creat_rf_sync_broadcast_event(msg, msg_len);
#else
  DS_app_log_error("RFM Not Supported\r\n");
#endif
}

static void UpdatemeGroupBC(ds_cli_command_arg_t *arguments)
{
  (void)arguments;
#ifdef HUB_DEVICE
  uint8_t bretry = ds_cli_get_argument_uint8(arguments, 0);
  uint8_t rfmid[UPDATEME_BC_ID_CN] = {0x00};
  for(unsigned char i = 0; i < sizeof(rfmid); i++){
      rfmid[i] = ds_cli_get_argument_uint8(arguments, (i+1));
  }
  uint8_t ctrl = ds_cli_get_argument_uint8(arguments, 13);

  unsigned char bcast_busy = 0;
  getThisParam(ENbyBcastBusy, (unsigned char *)&bcast_busy);
  if(bcast_busy){
      DS_app_log_error("BcastBusy\r\n");
      return;
  }
  uint8_t msg[16] = {0x00};
  int msg_len = 0;
  uint8_t id_mum = 0;

  msg[msg_len++] = bretry;
  msg[msg_len++] = 0x08;
  msg[msg_len++] = (id_mum + 1); //2
  msg[msg_len++] = ctrl;
  for(unsigned char i = 0; i < sizeof(rfmid); i++){
      if(rfmid[i] != 0x00 && rfmid[i] != 0xff){
          msg[msg_len++] = rfmid[i];
          id_mum++;
      }
  }
  if(id_mum){
      msg[2] = (id_mum + 1);
      DS_hub_api_creat_rf_sync_broadcast_event(msg, msg_len);
  }
#else
  DS_app_log_error("RFM Not Supported\r\n");
#endif
}

static void SwitchGroupBC(ds_cli_command_arg_t *arguments)
{
  (void)arguments;
#ifdef HUB_DEVICE
  uint8_t bretry = ds_cli_get_argument_uint8(arguments, 0);
  uint8_t no[SWITCH_BC_ID_CN] = {0xff};
  for(unsigned char i = 0; i < sizeof(no); i++){
      no[i] = ds_cli_get_argument_uint8(arguments, (i+1));
  }
  uint8_t option = ds_cli_get_argument_uint8(arguments, 13);

  unsigned char bcast_busy = 0;
  getThisParam(ENbyBcastBusy, (unsigned char *)&bcast_busy);
  if(bcast_busy){
      DS_app_log_error("BcastBusy\r\n");
      return;
  }
  uint8_t msg[28] = {0x00};
  int msg_len = 0;
  uint8_t no_mum = 0;

  msg[msg_len++] = bretry;
  msg[msg_len++] = 0x04;
  msg[msg_len++] = switch_bseq++;
  switch_bseq = switch_bseq & 0xff;
  if(switch_bseq == 0){
      switch_bseq = 2;
  }
  msg[msg_len++] = no_mum;  //3
  for(unsigned char i = 0; i < sizeof(no); i++){
      if(no[i] != 0xff){
          msg[msg_len++] = no[i];
          msg[msg_len++] = option;
          no_mum++;
      }
  }
  if(no_mum){
      msg[3] = no_mum * 2;
      DS_hub_api_creat_rf_sync_broadcast_event(msg, msg_len);
  }

#else
  DS_app_log_error("RFM Not Supported\r\n");
#endif
}

static void GroupBC(ds_cli_command_arg_t *arguments)
{
  (void)arguments;
#ifdef HUB_DEVICE
  uint8_t bretry = ds_cli_get_argument_uint8(arguments, 0);
  uint8_t bitmask0 = ds_cli_get_argument_uint8(arguments, 1);
  uint8_t bitmask1 = ds_cli_get_argument_uint8(arguments, 2);
  uint8_t opption = ds_cli_get_argument_uint8(arguments, 3);

  uint8_t ctrl = ds_cli_get_argument_uint8(arguments, 4);
  uint8_t rfmid = ds_cli_get_argument_uint8(arguments, 5);

  uint8_t i = 0;
  uint8_t msg[21] = {0x00};
  uint8_t msg_len = 0;

  unsigned char bcast_busy = 0;
  getThisParam(ENbyBcastBusy, (unsigned char *)&bcast_busy);
  if(bcast_busy){
      DS_app_log_error("BcastBusy\r\n");
      return;
  }

  msg[msg_len++] = bretry;
  msg[msg_len++] = 0x02;
  msg[msg_len++] = sounder_bseq++;
  sounder_bseq = sounder_bseq & 0xff;
  if(sounder_bseq == 0){
      sounder_bseq = 2;
  }
  msg[msg_len++] = bitmask0;
  msg[msg_len++] = bitmask1;
  for(i = 0; i < 12; i++){
      msg[msg_len++] = opption;
  }

  msg[msg_len++] = 0x08;
  msg[msg_len++] = 2;
  msg[msg_len++] = ctrl;
  msg[msg_len++] = rfmid;
  DS_hub_api_creat_rf_sync_broadcast_event(msg, msg_len);
#endif
}

static void GetLocalRegisterflag(ds_cli_command_arg_t *arguments)
{
  (void)arguments;
#ifdef HUB_DEVICE
  unsigned char flag = 0;
  getThisParam(ENbyLocalRegister, &flag);
  APP_PRINTF("register flag: %d\r\n", flag);
#else
  DS_app_log_error("RFM Not Supported\r\n");
#endif
}

static void GetHubPhysical(ds_cli_command_arg_t *arguments)
{
  (void)arguments;
#ifdef HUB_DEVICE
  unsigned char physical[64] = {0};
  get_device_state(physical);
  APP_PRINTF("physical : %02x %02x %02x %02x\r\n",physical[0],
             physical[1],physical[2],physical[3]);
#else
  DS_app_log_error("RFM Not Supported\r\n");
#endif
}

static void GetHubRssi(ds_cli_command_arg_t *arguments)
{
  (void)arguments;
#ifdef HUB_DEVICE
  signed char real_rssi = 0;
  signed char avg_rssi = 0;
  if(getThisParam(ENbyRealRssi, &real_rssi)){
      real_rssi = 0;
  }
  if(getThisParam(ENbyAvgRssi, &avg_rssi)){
      avg_rssi = 0;
  }
  DS_app_log_error("rssi : %d %d\r\n",real_rssi,avg_rssi);
  DS_app_log_error("to panel rssi : %d %d\r\n",(real_rssi+128),(avg_rssi+128));

#else
  DS_app_log_error("RFM Not Supported\r\n");
#endif
}

static void RfmInfo(ds_cli_command_arg_t *arguments)
{
  (void)arguments;
#ifdef HUB_DEVICE
  uint8_t rfmid = ds_cli_get_argument_uint8(arguments, 0);
  uint8_t qrfh1 = 0;
  uint8_t qrfh2 = 0;
  //uint8_t qrfr1 = 0;
  //uint8_t qrfr2 = 0;
  uint8_t opption[OPTION_LENGTH] = {0x00};
  uint8_t mac[MAC_ADDRESS_LENGTH] = {0x00};
  uint8_t sn[SN_LENGTH] = {0x00};
  uint8_t time = 0;
  uint8_t devicetype[3] = {0};
  uint8_t IOen_lock = 0;

  if(rfmid == 0 || rfmid == 0xff){
      DS_app_log_error("err rfmid\r\n");
      return;
  }

  getDeviceParam(rfmid, ENpbyNodeDeviceTypeFirst, devicetype);
  getNodeJoinMac(mac, rfmid);
  getDeviceParam(rfmid, ENpbyNodeSNFirst, sn);
  getDeviceParam(rfmid, ENbyIOenLock, &IOen_lock);

  if(check_rfm_is_offline(rfmid)){
      DS_app_log_error("rfmid:%02x, type:[%02x%02x%02x], ioen_lock:%d, is[offline]\r\n",
                       rfmid, devicetype[0],devicetype[1],devicetype[2], IOen_lock);
  }else{
      time = get_rfm_offline_countdown(rfmid);
      DS_app_log_error("rfmid:%02x, type:[%02x%02x%02x], ioen_lock:%d, since last[%d s]\r\n",
                       rfmid, devicetype[0],devicetype[1],devicetype[2], IOen_lock,
                       ((MAX_OFFLINE_COUNTDOWN - time)*10));
  }

  DS_app_log_hexdump_error("[MAC]",mac,MAC_ADDRESS_LENGTH);
  DS_app_log_hexdump_error("[SN]",sn,SN_LENGTH);

  getDeviceParam(rfmid, ENpbyNodeQrfH1First, &qrfh1);
  getDeviceParam(rfmid, ENpbyNodeQrfH2First, &qrfh2);
  //getDeviceParam(rfmid, ENpbyNodeQrfR1First, &qrfr1);
  //getDeviceParam(rfmid, ENpbyNodeQrfR2First, &qrfr2);
  getDeviceParam(rfmid, ENpbyNodeOptionFirst, opption);

  time = get_qrfh_countdown(rfmid);
  DS_app_log_error("qrfH:[%02x %02x], countdown:[%d s], opption:[%02x %02x %02x]\r\n",
                   qrfh1,qrfh2, (time*10), opption[0],opption[1],opption[2]);
#else
  DS_app_log_error("RFM Not Supported\r\n");
#endif
}

static void RegisterInfo(ds_cli_command_arg_t *arguments)
{
  (void)arguments;
#ifdef HUB_DEVICE
  uint8_t buf[NODE_JOIN_INFO_LENGTH];
  DS_app_log_error("register count: %d\r\n",getNodeJoinCount());
  getThisParam(ENbyNodeJoinInfo,buf);
  DS_app_log_hexdump_error("[register]",buf,NODE_JOIN_INFO_LENGTH);
#else
  DS_app_log_error("RFM Not Supported\r\n");
#endif
}

static void P2POption(ds_cli_command_arg_t *arguments)
{
  (void)arguments;
#ifdef HUB_DEVICE
  uint8_t msg[1+OPTION_LENGTH] ={0};
  uint8_t rfmid = ds_cli_get_argument_uint8(arguments, 0);
  if(rfmid == 0 || rfmid == 0xff){
      DS_app_log_error("err rfmid\r\n");
      return;
  }
  msg[0] = OPTION_KEY;
  msg[1] = ds_cli_get_argument_uint8(arguments, 1);
  msg[2] = ds_cli_get_argument_uint8(arguments, 2);
  msg[3] = ds_cli_get_argument_uint8(arguments, 3);
  setDeviceParam(rfmid, ENpbyNodeOptionFirst, &msg[1]);
  DS_hub_api_creat_rf_point_to_point_event(rfmid, msg, (1+OPTION_LENGTH));
#else
  DS_app_log_error("RFM Not Supported\r\n");
#endif
}

static void HubSetQRFH(ds_cli_command_arg_t *arguments)
{
  (void)arguments;
#ifdef HUB_DEVICE
  uint8_t rfmid = ds_cli_get_argument_uint8(arguments, 0);
  if(rfmid == 0 || rfmid == 0xff){
      DS_app_log_error("err rfmid\r\n");
      return;
  }
  uint8_t qrfh1 = ds_cli_get_argument_uint8(arguments, 1);
  uint8_t qrfh2 = ds_cli_get_argument_uint8(arguments, 2);

  setDeviceParam(rfmid, ENpbyNodeQrfH1First, (unsigned char *)&qrfh1);
  setDeviceParam(rfmid, ENpbyNodeQrfH2First, (unsigned char *)&qrfh2);

#else
  DS_app_log_error("RFM Not Supported\r\n");
#endif
}

static void SetOption(ds_cli_command_arg_t *arguments)
{
  (void)arguments;
#ifdef HUB_DEVICE
  uint8_t rfmid = ds_cli_get_argument_uint8(arguments, 0);
  if(rfmid == 0 || rfmid == 0xff){
      DS_app_log_error("err rfmid\r\n");
      return;
  }
  uint8_t option[OPTION_LENGTH] = {0};
  option[0] = ds_cli_get_argument_uint8(arguments, 1);
  option[1] = ds_cli_get_argument_uint8(arguments, 2);
  option[2] = ds_cli_get_argument_uint8(arguments, 3);
  setDeviceParam(rfmid, ENpbyNodeOptionFirst, (unsigned char *)option);

#else
  DS_app_log_error("RFM Not Supported\r\n");
#endif
}

static void SetOperateCtrl(ds_cli_command_arg_t *arguments)
{
  (void)arguments;
#ifdef HUB_DEVICE
  uint8_t rfmid = ds_cli_get_argument_uint8(arguments, 0);
  if(rfmid == 0 || rfmid == 0xff){
      DS_app_log_error("err rfmid\r\n");
      return;
  }
  uint8_t operate_ctrl[OPERATECTRL_LENGTH] = {0x00};
  uint8_t operate_flag = 1;
  updata_node_aseq(ASEQ_OPERATE, rfmid);
  operate_ctrl[0] = get_node_aseq(ASEQ_OPERATE, rfmid);
  operate_ctrl[1] = ds_cli_get_argument_uint8(arguments, 1);
  operate_ctrl[2] = ds_cli_get_argument_uint8(arguments, 2);
  operate_ctrl[3] = ds_cli_get_argument_uint8(arguments, 3);

  setDeviceParam(rfmid, ENbyOperateCtrl, (unsigned char *)operate_ctrl);
  setDeviceParam(rfmid, ENbyOperateCtrlFlag, (unsigned char *)&operate_flag);

#else
  DS_app_log_error("RFM Not Supported\r\n");
#endif
}

static void SetLedCtrl(ds_cli_command_arg_t *arguments)
{
  (void)arguments;
#ifdef HUB_DEVICE
  uint8_t rfmid = ds_cli_get_argument_uint8(arguments, 0);
  if(rfmid == 0 || rfmid == 0xff){
      DS_app_log_error("err rfmid\r\n");
      return;
  }
  uint8_t led_ctrl[LEDCTRL_LENGTH] = {0};
  uint8_t led_ctrl_flag = 1;
  updata_node_aseq(ASEQ_LED, rfmid);
  led_ctrl[0] = get_node_aseq(ASEQ_LED, rfmid);
  led_ctrl[1] = ds_cli_get_argument_uint8(arguments, 1);
  led_ctrl[2] = ds_cli_get_argument_uint8(arguments, 2);
  led_ctrl[3] = ds_cli_get_argument_uint8(arguments, 3);
  led_ctrl[4] = ds_cli_get_argument_uint8(arguments, 4);
  led_ctrl[5] = ds_cli_get_argument_uint8(arguments, 5);

  setDeviceParam(rfmid, ENbyLedCtrl, (unsigned char *)led_ctrl);
  setDeviceParam(rfmid, ENbyLedCtrlFlag, (unsigned char *)&led_ctrl_flag);

#else
  DS_app_log_error("RFM Not Supported\r\n");
#endif
}

static void P2PLedCtrl(ds_cli_command_arg_t *arguments)
{
  (void)arguments;
#ifdef HUB_DEVICE
  uint8_t rfmid = ds_cli_get_argument_uint8(arguments, 0);
  if(rfmid == 0 || rfmid == 0xff){
      DS_app_log_error("err rfmid\r\n");
      return;
  }
  uint8_t msg[1+LEDCTRL_LENGTH] ={0};
  updata_node_aseq(ASEQ_LED, rfmid);
  msg[0] = COMLED_CTRL_KEY;
  msg[1] = get_node_aseq(ASEQ_LED, rfmid);
  msg[2] = ds_cli_get_argument_uint8(arguments, 1);
  msg[3] = ds_cli_get_argument_uint8(arguments, 2);
  msg[4] = ds_cli_get_argument_uint8(arguments, 3);
  msg[5] = ds_cli_get_argument_uint8(arguments, 4);
  msg[6] = ds_cli_get_argument_uint8(arguments, 5);
  DS_hub_api_creat_rf_point_to_point_event(rfmid, msg, (1+LEDCTRL_LENGTH));
#else
  DS_app_log_error("RFM Not Supported\r\n");
#endif
}

static void P2POperateCtrl(ds_cli_command_arg_t *arguments)
{
  (void)arguments;
#ifdef HUB_DEVICE
  uint8_t rfmid = ds_cli_get_argument_uint8(arguments, 0);
  if(rfmid == 0 || rfmid == 0xff){
      DS_app_log_error("err rfmid\r\n");
      return;
  }
  uint8_t msg[1 + OPERATECTRL_LENGTH] = {0x00};
  updata_node_aseq(ASEQ_OPERATE, rfmid);
  msg[0] = OPERATE_CTRL_KEY;
  msg[1] = get_node_aseq(ASEQ_OPERATE, rfmid);
  msg[2] = ds_cli_get_argument_uint8(arguments, 1);
  msg[3] = ds_cli_get_argument_uint8(arguments, 2);
  msg[4] = ds_cli_get_argument_uint8(arguments, 3);
  DS_hub_api_creat_rf_point_to_point_event(rfmid, msg, (1 + OPERATECTRL_LENGTH));
#else
  DS_app_log_error("RFM Not Supported\r\n");
#endif
}

static void HubStartOta(ds_cli_command_arg_t *arguments) //HubStartOta,1,5,1,2,3,4,5
{
  (void)arguments;
#ifdef HUB_DEVICE
  uint8_t mode_pre = 0;
  uint8_t mode_now = 0;
  unsigned char num = 0;
  unsigned char id = 0;
  unsigned char id_max_num = 0;
  unsigned char id_buf[OTA_ID_BUF_MAX] = {0};
  unsigned char consult[OTA_CONSULT_KEYVALUE_LENGTH] = {
      0xfe,
      7, 0xff, 0x03,
      0x00,0x00,0x1c,0x00,  //模拟7168字节
      //0x00,0x00,0x38,0x00,  //模拟14336字节
      0x00,
  };

  getThisParam(ENbyPanelSetOtaMode,&mode_pre);
  mode_now = ds_cli_get_argument_uint8(arguments, 0);
  if(mode_pre){
      //正在OTA
      if(mode_now){
          DS_app_log_error("ota is busy\r\n");
          return;
      }else{
          setThisParam(ENbyPanelSetOtaMode, (unsigned char *)&mode_now);
          DS_app_log_error("ota stop\r\n");
          return;
      }
  }else{
      //没有进行OTA，panel继续do强制退出
      if(!mode_now){
          creat_ota_abort_event();
          DS_app_log_error("ota is stop\r\n");
          return;
      }
  }

  id_max_num = ds_cli_get_argument_uint8(arguments, 1);
  if(id_max_num > 5){
      DS_app_log_error("id too much\r\n");
      return;
  }
  for(int i = 0; i < id_max_num; i++){
      id = ds_cli_get_argument_uint8(arguments, (2+i));
      if(id != 0x00 && id != 0xff){
          id_buf[num++] = id;
      }
  }


  setThisParam(ENbyPanelSetOtaMode,&mode_now);
  setThisParam(ENbyPanelSetOtaNum, (unsigned char *)&num);
  setThisParam(ENbyPanelSetOtaId, (unsigned char *)id_buf);

  setThisParam(ENbyOtaUpdatemeIDNum, (unsigned char *)&num);
  setThisParam(ENbyOtaUpdatemeID, (unsigned char *)id_buf);

  setThisParam(ENbyTransFileType, (unsigned char *)&consult[3]);
  setThisParam(ENbyOtaConSultKeyValue, consult);
  ota_enter_hook();
  DS_app_log_error("ota start\r\n");
#else
  DS_app_log_error("RFM Not Supported\r\n");
#endif
}

static void annSelect(ds_cli_command_arg_t *arguments)
{
  uint8_t ann = ds_cli_get_argument_uint8(arguments, 0);

  bsp_rf_antenna_select(ann);
}

static void GetOtaInfo(ds_cli_command_arg_t *arguments)
{
  (void)arguments;
  printf_rfm_ota_info();
}

static void StopBC(ds_cli_command_arg_t *arguments)
{
  (void)arguments;
  unsigned char bcast_busy = 0;

  stop_twoway_broadcast_retry_timer();
  setThisParam(ENbyBcastBusy, (unsigned char *)&bcast_busy);
}

static void SetinvaildRfm(ds_cli_command_arg_t *arguments)
{
  (void)arguments;
  unsigned char rfmid = 0;
  unsigned char option = 0;
  unsigned char reboot = 0;

  rfmid = ds_cli_get_argument_uint8(arguments, 0);
  option = ds_cli_get_argument_uint8(arguments, 1);
  reboot = ds_cli_get_argument_uint8(arguments, 2);

  if(rfmid == 0 || rfmid == 0xff){
      APP_PRINTF("id[%d] not support!\n",rfmid);
  }
  else{
      reg_setInvaildRFMIdToRam(rfmid);
      setDeviceParam(rfmid,ENbyNodeDeviceOptionFirst,&option);
  }

  APP_PRINTF("set invaild ID[%d],option=%d\n",rfmid,option);
  reg_printfInvailID();

  if( reboot == 1 && rfmid != 0 &&  rfmid != 0xff ){

      //test
#if 0
      for(uint8_t i=1;i<100;i++){
          setDeviceParam(i,ENbyNodeDeviceOptionFirst,&option);
          setRfmIdToPacket(i); //TODO:正式发布此处注释
      }
      setRfmIdToPacket(rfmid);//TODO:正式发布此处注释
#endif
      NVIC_SystemReset();
  }

}
static void GetRfmMac(ds_cli_command_arg_t *arguments)
{
  (void)arguments;
  unsigned char rfmid = 0;
  rfmid = ds_cli_get_argument_uint8(arguments, 0);

  getAllNodeJoinMac();
  if(rfmid == 0xff || rfmid == 0){
      printAllNodeJoinMac();
  }
  else {
      printOneNodeJoinMac(rfmid);
  }

  //test cmp mac
//  uint8_t mac[8]={0x28,0x76,0x81,0xff,0xfe,0xc0,0x40,0x6d};//{0};
//  uint8_t mac[8]={0x28,0x76,0x81,0xff,0xfe,0xc0,0x40,0x61};
//
//  DS_app_func_tm_in();
//  isJoinMac(mac);
//  DS_app_func_tm_end("option:");

}

static void GetRFMMemSupportOTA(ds_cli_command_arg_t *arguments)
{
  (void)arguments;
  unsigned char rfmid = 0;
  rfmid = ds_cli_get_argument_uint8(arguments, 0);


  DS_app_log_error("ID[%d] Ota=%d\r\n",rfmid,checkRFMMemSupportOTA(rfmid));
}

static void SetHubRfReq(ds_cli_command_arg_t *arguments)
{
  (void)arguments;
  unsigned char freq = 0;
  freq = ds_cli_get_argument_uint8(arguments, 0);

  if(freq != getDeviceRfFreq()){
      setDeviceRfFreq(freq);
      NVIC_SystemReset();
  }

}
static void DeleteRfm(ds_cli_command_arg_t *arguments)
{
  (void)arguments;
  unsigned char rfmid = 0;
  rfmid = ds_cli_get_argument_uint8(arguments, 0);
  if(rfmid == 0){
      APP_PRINTF("err rfmid 0\r\n");
      return;
  }else if(rfmid == 0xff){
      APP_PRINTF("delete all rfm\r\n");
  }else{
      APP_PRINTF("delete rfm %d\r\n",rfmid);
  }
#ifndef CONFIG_NVM_VERSION
  unsigned char mac_addr[MAC_ADDRESS_LENGTH] = {0}; //删MAC地址
  unsigned char sn[SN_LENGTH] = {0}; //删SN
  unsigned char devicetype[3] = {0};
  unsigned char codeAB[KEY_MAX_LENGTH] = {0};
#endif
  unsigned char info[NODE_JOIN_INFO_LENGTH] = {0};  //删注册状态
  unsigned char option[OPTION_LENGTH] = {0};//删option
#ifndef CONFIG_NVM_VERSION
  unsigned char qrfh1 = 0;
  unsigned char qrfh2 = 0;
#endif
  unsigned char qrfr1 = 0;
  unsigned char qrfr2 = 0;
  unsigned char groupix = 0;
  unsigned char rollcode[ROLLING_CODE_LENGTH] = {0x00,0x00,0x00,0x00};
  unsigned char flag = 0;
  unsigned char led_ctrl[LEDCTRL_LENGTH] = {0};
  unsigned char operate_ctrl[OPERATECTRL_LENGTH] = {0};
  unsigned char keyvalue_get[GETKEYVALUE_LENGTH] = {0};
  int i = 0;
  unsigned char idx = 0;
  unsigned char bit = 0;
#ifdef CONFIG_NVM_VERSION
  uint8_t nodeRegInfo[NODEREGINFO_MAX_LEN]={0};
  uint8_t qrfh12[NodeQrfH12Group_MAX_LEN]={0};
#endif

  if(rfmid == 0xff){
      //删除全部设备
#ifndef CONFIG_NVM_VERSION
      setThisParam(ENbyNodeJoinInfo, (unsigned char *)info);
#endif
      for(i = 1; i < NODE_MAX_COUNT; i++){
#ifndef CONFIG_NVM_VERSION
          setNodeJoinCodeAB(codeAB, i);
          setNodeJoinMac(mac_addr, i);
          setDeviceParam(i, ENpbyNodeSNFirst, sn);
          setDeviceParam(i, ENpbyNodeOptionFirst, option);
          setDeviceParam(i, ENpbyNodeQrfH1First, &qrfh1);
          setDeviceParam(i, ENpbyNodeQrfH2First, &qrfh2);
          setDeviceParam(i, ENpbyNodeGroupIdxFirst, &groupix);
          setDeviceParam(i, HubRecvRollingCodeFirst, rollcode);
          setDeviceParam(i, ENpbyNodeDeviceTypeFirst, devicetype);
#endif
          clean_device_ram_qrfh_and_option(i); //nvm里的qrfh和option都被格式化了，这里删ram里的
          setDeviceParam(i, ENpbyNodeQrfR1First, &qrfr1);
          setDeviceParam(i, ENpbyNodeQrfR2First, &qrfr2);
          setDeviceParam(i, ENbyLedCtrlFlag, &flag);
          setDeviceParam(i, ENbyOperateCtrlFlag, &flag);
          setDeviceParam(i, ENbyKeyValueGetFlag, &flag);
          setDeviceParam(i, ENbyLedCtrl, led_ctrl);
          setDeviceParam(i, ENbyOperateCtrl, operate_ctrl);
          setDeviceParam(i, ENbyKeyValueGet, keyvalue_get);
          set_rfm_offline(i);
      }
#ifdef CONFIG_NVM_VERSION
#ifdef HUB_DEVICE
      device_hub_formatting();
#endif
#endif

  }else{
      //删除rfmid设备
      getThisParam(ENbyNodeJoinInfo, (unsigned char *)info);
      for(i = 0; i < NODE_JOIN_INFO_LENGTH; i++){
          APP_PRINTF("%02x ",info[i]);
      }
      idx = (rfmid - 1)/8;
      bit = (rfmid - 1)%8;
      HUB_API_CLEAN_BIT(info[idx], bit);
      setThisParam(ENbyNodeJoinInfo, (unsigned char *)info);
#ifdef CONFIG_NVM_VERSION
#ifdef HUB_DEVICE
      setNodeRegInfoPack(rfmid,nodeRegInfo);
      setNodeQrfH12Group(rfmid,qrfh12);
      clean_device_ram_qrfh(rfmid); //这里删ram里的qrfh
#endif
#else
      setNodeJoinMac(mac_addr, rfmid);
      setNodeJoinCodeAB(codeAB, rfmid);
      setDeviceParam(rfmid, ENpbyNodeSNFirst, sn);
      setDeviceParam(rfmid, ENpbyNodeQrfH1First, &qrfh1);
      setDeviceParam(rfmid, ENpbyNodeQrfH2First, &qrfh2);
      setDeviceParam(rfmid, ENpbyNodeDeviceTypeFirst, devicetype);
#endif
      setDeviceParam(rfmid, ENpbyNodeOptionFirst, option); //删ram和nvm里的option
      setDeviceParam(rfmid, ENpbyNodeQrfR1First, &qrfr1);
      setDeviceParam(rfmid, ENpbyNodeQrfR2First, &qrfr2);
      setDeviceParam(rfmid, ENpbyNodeGroupIdxFirst, &groupix);
      setDeviceParam(rfmid, HubRecvRollingCodeFirst, rollcode);
      setDeviceParam(rfmid, ENbyLedCtrlFlag, &flag);
      setDeviceParam(rfmid, ENbyOperateCtrlFlag, &flag);
      setDeviceParam(rfmid, ENbyKeyValueGetFlag, &flag);
      setDeviceParam(rfmid, ENbyLedCtrl, led_ctrl);
      setDeviceParam(rfmid, ENbyOperateCtrl, operate_ctrl);
      setDeviceParam(rfmid, ENbyKeyValueGet, keyvalue_get);
      set_rfm_offline(rfmid);
  }
  getAllNodeJoinMac();
}

//恢复出厂设置  
static void FactoryRfm(ds_cli_command_arg_t *arguments)
{
 (void)arguments;
  unsigned char rfmid = 0;
  rfmid = ds_cli_get_argument_uint8(arguments, 0);
  if(rfmid == 0 || rfmid == 0xff){
      APP_PRINTF("err rfmid 0\r\n");
      return;
  }else{
      APP_PRINTF("Factory rfm %d\r\n",rfmid);
  }

//初始指令
  uint8_t led_ctrl[LEDCTRL_LENGTH] = {0, 0xDE, 0xCA, 0x01, 0, 0};
  uint8_t led_ctrl_flag = 1;
  updata_node_aseq(ASEQ_LED, rfmid);
  led_ctrl[0] = get_node_aseq(ASEQ_LED, rfmid);

  setDeviceParam(rfmid, ENbyLedCtrl, (unsigned char *)led_ctrl);
  setDeviceParam(rfmid, ENbyLedCtrlFlag, (unsigned char *)&led_ctrl_flag);

//update me 
  uint8_t msg[16] = {0x00};
  int msg_len = 0;
  uint8_t id_mum = 1;

  msg[msg_len++] = 3;//bretry;
  msg[msg_len++] = 0x08;
  msg[msg_len++] = 2;//(id_mum + 1); //2
  msg[msg_len++] = 0x00;//ctrl;
  msg[msg_len++] = rfmid;
  if(id_mum){
      msg[2] = (id_mum + 1);
      DS_hub_api_creat_rf_sync_broadcast_event(msg, msg_len);
  }
}

#ifdef HUB_AS_TEST_MACHINE
const char TEST_RFM_CMD_INFO[][20] =
{
  "NULL",
  "FactoryRfm",
  "TH_DISPLA_ALL_ON",
  "TH_DISPLA_ALL_OFF",
  "TH_DISPLA_ALL_EXIT",
  "PL_RESET_CAL",
  "RFM_CFG_868M",
  "RFM_CFG_915M",
  "RFM_CFG_433M",
  "RFM_CFG_915M_RCM",
  "RFM_CFG_868M_WPC",
};
//测试子设备功能  
static void TestRfm(ds_cli_command_arg_t *arguments)
{
 (void)arguments;
  unsigned char rfmid = 0;
  unsigned char cmd = 0;
  rfmid = ds_cli_get_argument_uint8(arguments, 0);
  if(rfmid == 0 || rfmid == 0xff){
      APP_PRINTF("err rfmid\r\n");
      return;
  }else{
      APP_PRINTF("rfm[%d] ",rfmid);
  }
  
  cmd = ds_cli_get_argument_uint8(arguments, 1);
  if(TEST_RFM_CMD_START >= cmd || TEST_RFM_CMD_STOP <= cmd){ //cmd从1开始
      APP_PRINTF("err cmd %d\r\n",cmd);
      return;
  }else{
      APP_PRINTF("CMD[%d]:%s\r\n",cmd,TEST_RFM_CMD_INFO[cmd]);
  }
//初始指令
  uint8_t led_ctrl[LEDCTRL_LENGTH] = {0, 0xDE, 0xCA, cmd, 0, 0};//第一字节使用cmd代替
  uint8_t led_ctrl_flag = 1;

  updata_node_aseq(ASEQ_LED, rfmid);
  led_ctrl[0] = get_node_aseq(ASEQ_LED, rfmid);

  setDeviceParam(rfmid, ENbyLedCtrl, (unsigned char *)led_ctrl);
  setDeviceParam(rfmid, ENbyLedCtrlFlag, (unsigned char *)&led_ctrl_flag);

//update me 
  uint8_t msg[16] = {0x00};
  int msg_len = 0;
  uint8_t id_mum = 1;

  msg[msg_len++] = 3;//bretry;
  msg[msg_len++] = 0x08;
  msg[msg_len++] = 2;//(id_mum + 1); //2
  msg[msg_len++] = 0x00;//ctrl;
  msg[msg_len++] = rfmid;
  if(id_mum){
      msg[2] = (id_mum + 1);
      DS_hub_api_creat_rf_sync_broadcast_event(msg, msg_len);
  }
}

#endif
#endif
/**************************************************************/

static const ds_cli_command_info_t cli_cmd_help = \
    DS_CLI_COMMAND(help,
                 {DS_CLI_ARG_END, });

static const ds_cli_command_info_t cli_cmd__get_mac_info = \
    DS_CLI_COMMAND(get_mac_info,
                 {DS_CLI_ARG_END, });

static const ds_cli_command_info_t cli_cmd__set_tx_power = \
    DS_CLI_COMMAND(set_tx_power,
                 {DS_CLI_ARG_INT16, DS_CLI_ARG_END, });

static const ds_cli_command_info_t cli_cmd_get_tx_power = \
    DS_CLI_COMMAND(get_tx_power,
                 {DS_CLI_ARG_END, });

static const ds_cli_command_info_t cli_cmd_rx = \
    DS_CLI_COMMAND(rx,
                 {DS_CLI_ARG_UINT8, DS_CLI_ARG_END, });

static const ds_cli_command_info_t cli_cmd_get_channel = \
    DS_CLI_COMMAND(get_channel,
                 {DS_CLI_ARG_END, });

static const ds_cli_command_info_t cli_cmd_set_channel = \
    DS_CLI_COMMAND(set_channel,
                 {DS_CLI_ARG_UINT16, DS_CLI_ARG_END, });

static const ds_cli_command_info_t cli_cmd_start_tx_tone = \
    DS_CLI_COMMAND(start_tx_tone,
                 {DS_CLI_ARG_UINT8, DS_CLI_ARG_UINT8,
                     DS_CLI_ARG_UINT8, DS_CLI_ARG_END, });

static const ds_cli_command_info_t cli_cmd_set_ctune = \
    DS_CLI_COMMAND(set_ctune,
                 {DS_CLI_ARG_UINT32, DS_CLI_ARG_END, });

static const ds_cli_command_info_t cli_cmd_get_ctune = \
    DS_CLI_COMMAND(get_ctune,
                 {DS_CLI_ARG_END, });

static const ds_cli_command_info_t cli_cmd_set_lfxo_ctune = \
    DS_CLI_COMMAND(set_lfxo_ctune,
                 {DS_CLI_ARG_UINT8, DS_CLI_ARG_END, });

static const ds_cli_command_info_t cli_cmd_antenna_config = \
    DS_CLI_COMMAND(antenna_config,
                 {DS_CLI_ARG_UINT8, DS_CLI_ARG_END, });

static const ds_cli_command_info_t cli_cmd_get_raw_rssi = \
    DS_CLI_COMMAND(get_raw_rssi,
                 {DS_CLI_ARG_UINT8, DS_CLI_ARG_END, });

static const ds_cli_command_info_t cli_cmd_reset = \
    DS_CLI_COMMAND(reset,
                 {DS_CLI_ARG_END, });

static const ds_cli_command_info_t cli_cmd_enable_xmodem = \
    DS_CLI_COMMAND(enable_xmodem,
                 {DS_CLI_ARG_END, });

static const ds_cli_command_info_t cli_cmd_clk_out_pin_config = \
    DS_CLI_COMMAND(clk_out_pin_config,
                 {DS_CLI_ARG_STRING, DS_CLI_ARG_STRING,
                  DS_CLI_ARG_UINT8, DS_CLI_ARG_END, });

static const ds_cli_command_info_t cli_cmd_SN_set = \
    DS_CLI_COMMAND(SN_set,
                 {DS_CLI_ARG_STRING, DS_CLI_ARG_END, });

static const ds_cli_command_info_t cli_cmd_SN_get = \
    DS_CLI_COMMAND(SN_get,
                 {DS_CLI_ARG_END, });

static const ds_cli_command_info_t cli_cmd_soft_version_get = \
    DS_CLI_COMMAND(soft_version_get,
                 {DS_CLI_ARG_END, });

static const ds_cli_command_info_t cli_cmd_ResetNvm = \
    DS_CLI_COMMAND(ResetNvm,
                 {DS_CLI_ARG_END, });

static const ds_cli_command_info_t cli_cmd_FileLogEnable = \
    DS_CLI_COMMAND(FileLogEnable,
                 {DS_CLI_ARG_UINT8, DS_CLI_ARG_END, });

static const ds_cli_command_info_t cli_cmd_NetLogEnable = \
    DS_CLI_COMMAND(NetLogEnable,
                 {DS_CLI_ARG_UINT8, DS_CLI_ARG_END, });

static const ds_cli_command_info_t cli_cmd_MACLogEnable = \
    DS_CLI_COMMAND(MACLogEnable,
                 {DS_CLI_ARG_UINT8, DS_CLI_ARG_END, });

static const ds_cli_command_info_t cli_cmd_LogEnable = \
    DS_CLI_COMMAND(LogEnable,
                   {DS_CLI_ARG_UINT8, DS_CLI_ARG_UINT8,
                    DS_CLI_ARG_UINT8, DS_CLI_ARG_UINT8,
                    DS_CLI_ARG_END, });

#ifdef RFM_DEVICE
static const ds_cli_command_info_t cli_cmd_led_blink = \
    DS_CLI_COMMAND(led_blink,
                 {DS_CLI_ARG_UINT8, DS_CLI_ARG_UINT8,
                  DS_CLI_ARG_UINT8, DS_CLI_ARG_UINT8,
                  DS_CLI_ARG_UINT8, DS_CLI_ARG_END, });

static const ds_cli_command_info_t cli_cmd_get_battery = \
    DS_CLI_COMMAND(get_battery,
                 {DS_CLI_ARG_END, });

static const ds_cli_command_info_t cli_cmd_get_temperature = \
    DS_CLI_COMMAND(get_temperature,
                 {DS_CLI_ARG_END, });

static const ds_cli_command_info_t cli_cmd_option_set = \
    DS_CLI_COMMAND(option_set,
                 {DS_CLI_ARG_UINT8, DS_CLI_ARG_UINT8,
                  DS_CLI_ARG_UINT8, DS_CLI_ARG_END, });

static const ds_cli_command_info_t cli_cmd_operate_set = \
    DS_CLI_COMMAND(operate_set,
                 {DS_CLI_ARG_UINT8, DS_CLI_ARG_UINT8,
                  DS_CLI_ARG_UINT8, DS_CLI_ARG_END, });

static const ds_cli_command_info_t cli_cmd_qrf_set = \
    DS_CLI_COMMAND(qrf_set,
                 {DS_CLI_ARG_UINT8, DS_CLI_ARG_UINT8,
                  DS_CLI_ARG_END, });

static const ds_cli_command_info_t cli_cmd_relay_status_set = \
    DS_CLI_COMMAND(relay_status_set,
                 {DS_CLI_ARG_UINT8, DS_CLI_ARG_END, });

static const ds_cli_command_info_t cli_cmd_key_pad_led = \
    DS_CLI_COMMAND(key_pad_led,
                 {DS_CLI_ARG_UINT8, DS_CLI_ARG_UINT8,
                  DS_CLI_ARG_END, });

static const ds_cli_command_info_t cli_cmd_pir_enable = \
    DS_CLI_COMMAND(pir_enable,
                 {DS_CLI_ARG_UINT8, DS_CLI_ARG_UINT16,
                  DS_CLI_ARG_UINT32, DS_CLI_ARG_END, });

static const ds_cli_command_info_t cli_cmd_SetRfmRfReq = \
    DS_CLI_COMMAND(SetRfmRfReq,
                   {DS_CLI_ARG_UINT8, DS_CLI_ARG_END, });
#endif
#ifdef HUB_DEVICE
static const ds_cli_command_info_t cli_cmd_HubLogEnable = \
    DS_CLI_COMMAND(HubLogEnable,
                 {DS_CLI_ARG_UINT8, DS_CLI_ARG_END, });

static const ds_cli_command_info_t cli_cmd_SN_register = \
    DS_CLI_COMMAND(SN_register,
                 {DS_CLI_ARG_STRING, DS_CLI_ARG_END, });

static const ds_cli_command_info_t cli_cmd_RegisterMode = \
    DS_CLI_COMMAND(RegisterMode,
                 {DS_CLI_ARG_UINT8, DS_CLI_ARG_END, });

static const ds_cli_command_info_t cli_cmd_IOenBC = \
    DS_CLI_COMMAND(IOenBC,
                 {DS_CLI_ARG_UINT8, DS_CLI_ARG_UINT8,
                  DS_CLI_ARG_UINT8, DS_CLI_ARG_END, });

static const ds_cli_command_info_t cli_cmd_SounderBC = \
    DS_CLI_COMMAND(SounderBC,
                 {DS_CLI_ARG_UINT8, DS_CLI_ARG_UINT8,
                  DS_CLI_ARG_UINT8, DS_CLI_ARG_UINT8,
                  DS_CLI_ARG_END, });

static const ds_cli_command_info_t cli_cmd_KeypadBC = \
    DS_CLI_COMMAND(KeypadBC,
                 {DS_CLI_ARG_UINT8, DS_CLI_ARG_UINT8,
                  DS_CLI_ARG_UINT8, DS_CLI_ARG_END, });

static const ds_cli_command_info_t cli_cmd_UpdatemeBC = \
    DS_CLI_COMMAND(UpdatemeBC,
                 {DS_CLI_ARG_UINT8, DS_CLI_ARG_UINT8,
                  DS_CLI_ARG_UINT8, DS_CLI_ARG_END, });

static const ds_cli_command_info_t cli_cmd_SwitchBC = \
    DS_CLI_COMMAND(SwitchBC,
                 {DS_CLI_ARG_UINT8, DS_CLI_ARG_UINT8,
                  DS_CLI_ARG_UINT8, DS_CLI_ARG_END, });

static const ds_cli_command_info_t cli_cmd_UpdatemeGroupBC = \
    DS_CLI_COMMAND(UpdatemeGroupBC,
                   {DS_CLI_ARG_UINT8, DS_CLI_ARG_UINT8,
                    DS_CLI_ARG_UINT8, DS_CLI_ARG_UINT8,
                    DS_CLI_ARG_UINT8, DS_CLI_ARG_UINT8,
                    DS_CLI_ARG_UINT8, DS_CLI_ARG_UINT8,
                    DS_CLI_ARG_UINT8, DS_CLI_ARG_UINT8,
                    DS_CLI_ARG_UINT8, DS_CLI_ARG_UINT8,
                    DS_CLI_ARG_UINT8, DS_CLI_ARG_UINT8,
                    DS_CLI_ARG_END, });

static const ds_cli_command_info_t cli_cmd_SwitchGroupBC = \
    DS_CLI_COMMAND(SwitchGroupBC,
                 {DS_CLI_ARG_UINT8, DS_CLI_ARG_UINT8,
                  DS_CLI_ARG_UINT8, DS_CLI_ARG_UINT8,
                  DS_CLI_ARG_UINT8, DS_CLI_ARG_UINT8,
                  DS_CLI_ARG_UINT8, DS_CLI_ARG_UINT8,
                  DS_CLI_ARG_UINT8, DS_CLI_ARG_UINT8,
                  DS_CLI_ARG_UINT8, DS_CLI_ARG_UINT8,
                  DS_CLI_ARG_UINT8, DS_CLI_ARG_UINT8,
                  DS_CLI_ARG_END, });

static const ds_cli_command_info_t cli_cmd_GroupBC = \
    DS_CLI_COMMAND(GroupBC,
                 {DS_CLI_ARG_UINT8, DS_CLI_ARG_UINT8,
                  DS_CLI_ARG_UINT8, DS_CLI_ARG_UINT8,
                  DS_CLI_ARG_UINT8, DS_CLI_ARG_UINT8,
                  DS_CLI_ARG_END, });

static const ds_cli_command_info_t cli_cmd_GetLocalRegisterflag = \
    DS_CLI_COMMAND(GetLocalRegisterflag,
                 {DS_CLI_ARG_END, });

static const ds_cli_command_info_t cli_cmd_GetHubPhysical = \
    DS_CLI_COMMAND(GetHubPhysical,
                   {DS_CLI_ARG_END, });

static const ds_cli_command_info_t cli_cmd_GetHubRssi = \
    DS_CLI_COMMAND(GetHubRssi,
                   {DS_CLI_ARG_END, });

static const ds_cli_command_info_t cli_cmd_RfmInfo = \
    DS_CLI_COMMAND(RfmInfo,
                   {DS_CLI_ARG_UINT8,DS_CLI_ARG_END, });

static const ds_cli_command_info_t cli_cmd_RegisterInfo = \
    DS_CLI_COMMAND(RegisterInfo,
                   {DS_CLI_ARG_END, });

static const ds_cli_command_info_t cli_cmd_P2POption = \
    DS_CLI_COMMAND(P2POption,
                   {DS_CLI_ARG_UINT8, DS_CLI_ARG_UINT8,
                    DS_CLI_ARG_UINT8, DS_CLI_ARG_UINT8,
                   DS_CLI_ARG_END, });

static const ds_cli_command_info_t cli_cmd_HubSetQRFH = \
    DS_CLI_COMMAND(HubSetQRFH,
                   {DS_CLI_ARG_UINT8, DS_CLI_ARG_UINT8,
                    DS_CLI_ARG_UINT8, DS_CLI_ARG_END, });

static const ds_cli_command_info_t cli_cmd_SetOption = \
    DS_CLI_COMMAND(SetOption,
                   {DS_CLI_ARG_UINT8, DS_CLI_ARG_UINT8,
                    DS_CLI_ARG_UINT8, DS_CLI_ARG_UINT8,
                   DS_CLI_ARG_END, });

static const ds_cli_command_info_t cli_cmd_SetOperateCtrl = \
    DS_CLI_COMMAND(SetOperateCtrl,
                   {DS_CLI_ARG_UINT8, DS_CLI_ARG_UINT8,
                    DS_CLI_ARG_UINT8, DS_CLI_ARG_UINT8,
                   DS_CLI_ARG_END, });

static const ds_cli_command_info_t cli_cmd_SetLedCtrl = \
    DS_CLI_COMMAND(SetLedCtrl,
                   {DS_CLI_ARG_UINT8, DS_CLI_ARG_UINT8,
                    DS_CLI_ARG_UINT8, DS_CLI_ARG_UINT8,
                    DS_CLI_ARG_UINT8, DS_CLI_ARG_UINT8,
                    DS_CLI_ARG_END, });

static const ds_cli_command_info_t cli_cmd_P2PLedCtrl = \
    DS_CLI_COMMAND(P2PLedCtrl,
                   {DS_CLI_ARG_UINT8, DS_CLI_ARG_UINT8,
                    DS_CLI_ARG_UINT8, DS_CLI_ARG_UINT8,
                    DS_CLI_ARG_UINT8, DS_CLI_ARG_UINT8,
                    DS_CLI_ARG_END, });

static const ds_cli_command_info_t cli_cmd_P2POperateCtrl = \
    DS_CLI_COMMAND(P2POperateCtrl,
                   {DS_CLI_ARG_UINT8, DS_CLI_ARG_UINT8,
                    DS_CLI_ARG_UINT8, DS_CLI_ARG_UINT8,
                   DS_CLI_ARG_END, });

static const ds_cli_command_info_t cli_cmd_HubStartOta = \
    DS_CLI_COMMAND(HubStartOta,
                   {DS_CLI_ARG_UINT8, DS_CLI_ARG_UINT8,
                    DS_CLI_ARG_UINT8, DS_CLI_ARG_UINT8,
                    DS_CLI_ARG_UINT8, DS_CLI_ARG_UINT8,
                    DS_CLI_ARG_UINT8, DS_CLI_ARG_END, });

static const ds_cli_command_info_t cli_cmd_annSelect = \
    DS_CLI_COMMAND(annSelect,
                   {DS_CLI_ARG_UINT8, DS_CLI_ARG_END, });

static const ds_cli_command_info_t cli_cmd_GetOtaInfo = \
    DS_CLI_COMMAND(GetOtaInfo,
                   {DS_CLI_ARG_END, });

static const ds_cli_command_info_t cli_cmd_StopBC = \
    DS_CLI_COMMAND(StopBC,
                   {DS_CLI_ARG_END, });

static const ds_cli_command_info_t cli_cmd_DeleteRfm = \
    DS_CLI_COMMAND(DeleteRfm,
                   {DS_CLI_ARG_UINT8, DS_CLI_ARG_END, });

static const ds_cli_command_info_t cli_cmd_SetinvaildRfm = \
    DS_CLI_COMMAND(SetinvaildRfm,
                   {DS_CLI_ARG_UINT8,DS_CLI_ARG_UINT8, DS_CLI_ARG_UINT8, DS_CLI_ARG_END, });

static const ds_cli_command_info_t cli_cmd_GetRfmMac = \
    DS_CLI_COMMAND(GetRfmMac,
                   {DS_CLI_ARG_UINT8, DS_CLI_ARG_END, });

static const ds_cli_command_info_t cli_cmd_FactoryRfm = \
    DS_CLI_COMMAND(FactoryRfm,
                   {DS_CLI_ARG_UINT8, DS_CLI_ARG_END, });

#ifdef HUB_AS_TEST_MACHINE
static const ds_cli_command_info_t cli_cmd_TestRfm = \
    DS_CLI_COMMAND(TestRfm,
                   {DS_CLI_ARG_UINT8, DS_CLI_ARG_UINT8, DS_CLI_ARG_END, });
#endif
static const ds_cli_command_info_t cli_cmd_GetRFMMemSupportOTA = \
    DS_CLI_COMMAND(GetRFMMemSupportOTA,
                   {DS_CLI_ARG_UINT8, DS_CLI_ARG_END, });
static const ds_cli_command_info_t cli_cmd_SetHubRfReq = \
    DS_CLI_COMMAND(SetHubRfReq,
                   {DS_CLI_ARG_UINT8, DS_CLI_ARG_END, });
#endif
/**************************************************************/

const ds_cli_command_entry_t ds_cli_default_command_table[] = {
    { "help",                       &cli_cmd_help,                         "Inquire command list; separator: , "},
    { "getMacInfo",                 &cli_cmd__get_mac_info,                "get mac address"},
    { "setTxPower",                 &cli_cmd__set_tx_power,                "set tx power, unit:0.1dbm"},
    { "getTxPower",                 &cli_cmd_get_tx_power,                 "get tx power"},
    { "rx",                         &cli_cmd_rx,                           "[0]:disable, [1]:enable"},
    { "getChannel",                 &cli_cmd_get_channel,                  "get current channel"},
    { "setChannel",                 &cli_cmd_set_channel,                  "set channel"},
    { "startTxTone",                &cli_cmd_start_tx_tone,                "[enable]:0,stop,1,start;[mode]:0 unmodulated carrier wave,1,PN9;[annt]"},
    { "setCtune",                   &cli_cmd_set_ctune,                    "set ctune"},
    { "getCtune",                   &cli_cmd_get_ctune,                    "get ctune"},
    { "setLfxoCtune",               &cli_cmd_set_lfxo_ctune,               "set lfxo ctune"},
    { "antennaConfig",              &cli_cmd_antenna_config,               "antenna config,[antenna]"},
    { "getRawRssi",                 &cli_cmd_get_raw_rssi,                 "getRawRssi,[enable]"},
    { "reset",                      &cli_cmd_reset,                        "software reset"},
    { "enableXmodem",               &cli_cmd_enable_xmodem,                "enable xmodem"},
    { "clkOutPinConfig",            &cli_cmd_clk_out_pin_config,           "clkOutPinConfig,[L/H],[AB/CD],0"},
    { "SNSet",                      &cli_cmd_SN_set,                       "SNSet,[string]"},
    { "SNGet",                      &cli_cmd_SN_get,                       "SNGet"},
    { "softVersionGet",             &cli_cmd_soft_version_get,             "softVersionGet"},
    { "ResetNvm",                   &cli_cmd_ResetNvm,                     "ResetNvm"},
    { "FileLogEnable",              &cli_cmd_FileLogEnable,                "FileLogEnable,[0/1]"},
    { "NetLogEnable",               &cli_cmd_NetLogEnable,                 "NetLogEnable,[0/1]"},
    { "MACLogEnable",               &cli_cmd_MACLogEnable,                 "MACLogEnable,[0/1]"},
    { "LogEnable",                  &cli_cmd_LogEnable,                    "LogEnable,[bitmask],[bitmask],[bitmask],[bitmask]"},
#ifdef RFM_DEVICE
    { "ledBlink",                   &cli_cmd_led_blink,                    "led blink:[R][G][B][bitTimer][times]"},
    { "getBattery",                 &cli_cmd_get_battery,                  "get battery"},
    { "getTemperature",             &cli_cmd_get_temperature,              "get mcu temperature"},
    { "optionSet",                  &cli_cmd_option_set,                   "optionSet,[0],[1],[2]"},
    { "operateSet",                 &cli_cmd_operate_set,                  "operateSet,[0],[1],[2]"},
    { "qrfSet",                     &cli_cmd_qrf_set,                      "qrfSet,[0],[1]"},
    { "relayStatusSet",             &cli_cmd_relay_status_set,             "relayStatusSet,[status]"},
    { "keyPadLed",                  &cli_cmd_key_pad_led,                  "keyPadLed,[led],[state]"},
    { "pirEnable",                  &cli_cmd_pir_enable,                   "pirEnable,[enable],[cnt],[times:ms]"},
    { "SetRfmRfReq",                &cli_cmd_SetRfmRfReq,                  "SetRfmRfReq,[freq]"},
#endif
#ifdef HUB_DEVICE
    { "HubLogEnable",               &cli_cmd_HubLogEnable,                "HubLogEnable,[0/1]"},
    { "SNRegister",                 &cli_cmd_SN_register,                 "SNRegister,[string]"},
    { "RegisterMode",               &cli_cmd_RegisterMode,                "RegisterMode,[Mode]"},
    { "IOenBC",                     &cli_cmd_IOenBC,                      "IOenBC,[bretry],[bitmask],[bitmask]"},
    { "SounderBC",                  &cli_cmd_SounderBC,                   "SounderBC,[bretry],[bitmask],[bitmask],[opption]"},
    { "KeypadBC",                   &cli_cmd_KeypadBC,                    "KeypadBC,[bretry],[bitmask],[opption]"},
    { "UpdatemeBC",                 &cli_cmd_UpdatemeBC,                  "UpdatemeBC,[bretry],[ID],[ctrl]"},
    { "SwitchBC",                   &cli_cmd_SwitchBC,                    "SwitchBC,[bretry],[no],[option]"},
    { "UpdatemeGroupBC",            &cli_cmd_UpdatemeGroupBC,             "UpdatemeGroupBC,[bretry],[ID],[ID],[ID],[ID],[ID],[ID],[ID],[ID],[ID],[ID],[ID],[ID],[ctrl]"},
    { "SwitchGroupBC",              &cli_cmd_SwitchGroupBC,               "SwitchGroupBC,[bretry],[no],[no],[no],[no],[no],[no],[no],[no],[no],[no],[no],[no],[option]"},
    { "GroupBC",                    &cli_cmd_GroupBC,                     "GroupBC,[bretry],[bitmask],[bitmask],[opption],[ctrl],[ID]"},
    { "GetLocalRegisterflag",       &cli_cmd_GetLocalRegisterflag,        "GetLocalRegisterflag"},
    { "GetHubPhysical",             &cli_cmd_GetHubPhysical,              "GetHubPhysical"},
    { "GetHubRssi",                 &cli_cmd_GetHubRssi,                  "GetHubRssi"},
    { "RfmInfo",                    &cli_cmd_RfmInfo,                     "RfmInfo,[rfmid]"},
    { "RegisterInfo",               &cli_cmd_RegisterInfo,                "RegisterInfo"},
    { "P2POption",                  &cli_cmd_P2POption,                   "P2POption,[rfmid],[option],[option],[option]"},
    { "HubSetQRFH",                 &cli_cmd_HubSetQRFH,                  "HubSetQRFH,[rfmid],[QRFH1],[QRFH2]"},
    { "HubSetOption",               &cli_cmd_SetOption,                   "HubSetOption,[rfmid],[option],[option],[option]"},
    { "HubSetOperateCtrl",          &cli_cmd_SetOperateCtrl,              "HubSetOperateCtrl,[rfmid],[operate],[operate],[operate]"},
    { "HubSetLedCtrl",              &cli_cmd_SetLedCtrl,                  "HubSetLedCtrl,[rfmid],[R],[G],[B],[Time],[Cycle]"},
    { "P2PLedCtrl",                 &cli_cmd_P2PLedCtrl,                  "P2PLedCtrl,[rfmid],[R],[G],[B],[Time],[Cycle]"},
    { "P2POperateCtrl",             &cli_cmd_P2POperateCtrl,              "P2POperateCtrl,[rfmid],[operate],[operate],[operate]"},
    { "HubStartOta",                &cli_cmd_HubStartOta,                 "HubStartOta,[0/1],[num],[id],[id],[id],[id],[id]"},
    { "annSelect",                  &cli_cmd_annSelect,                   "annSelect,[ann] 0:internal 1:external"},
    { "GetOtaInfo",                 &cli_cmd_GetOtaInfo,                  "GetOtaInfo"},
    { "StopBC",                     &cli_cmd_StopBC,                      "StopBC"},
    { "DeleteRfm",                  &cli_cmd_DeleteRfm,                   "DeleteRfm,[rfmid]"},
    { "SetinvaildRfm",              &cli_cmd_SetinvaildRfm,               "SetinvaildRfm,[rfmid],[option],[reboot]"},
    { "GetRfmMac",                  &cli_cmd_GetRfmMac,                   "GetRfmMac"},
    { "FactoryRfm",                 &cli_cmd_FactoryRfm,                  "FactoryRfm,[rfmid]"},//初始化子设备 并在hub删除子设备
  #ifdef HUB_AS_TEST_MACHINE
    { "TestRfm",                    &cli_cmd_TestRfm,                     "TestRfm,[rfmid],[cmd]"},//测试子设备cmd对应功能
  #endif
    { "GetRFMMemSupportOTA",        &cli_cmd_GetRFMMemSupportOTA,         "GetRFMMemSupportOTA"},
    { "SetHubRfReq",                &cli_cmd_SetHubRfReq,                 "SetHubRfReq,[freq]"},
#endif
    { NULL, NULL, NULL},
};

static void help(ds_cli_command_arg_t *arguments)
{
  (void)arguments;
  uint8_t i = 0x00;
#if(1)
  char msg[255] = {0x00};
  int msg_len = 0;

  watchDogFeed();
  //DS_app_func_tm_in();
  msg_len = sprintf(msg,"%s\r\n","===========================cmd list==========================");
  msg[msg_len] = '\0';
  DS_debugTxbuff((uint8_t *)msg, strlen(msg));
  while(ds_cli_default_command_table[i].name){
      msg_len = sprintf(msg,"%s%*s%s\r\n",ds_cli_default_command_table[i].name,
                        24-strlen(ds_cli_default_command_table[i].name), " ",ds_cli_default_command_table[i].description);
      msg[msg_len] = '\0';
      DS_debugTxbuff((uint8_t *)msg, strlen(msg));
      i++;
  }
  msg_len = sprintf(msg,"%s\r\n","=============================================================");
  msg[msg_len] = '\0';
  DS_debugTxbuff((uint8_t *)msg, strlen(msg));
  //DS_app_func_tm_end("help"); //hub打印大概322.65ms 01-31
  watchDogFeed();
#else
  APP_PRINTF("===========================cmd list==========================\r\n");
  while(ds_cli_default_command_table[i].name){
      APP_PRINTF("%s%*s", ds_cli_default_command_table[i].name, 24-strlen(ds_cli_default_command_table[i].name), " ");
      APP_PRINTF("%s\r\n", ds_cli_default_command_table[i].description);
      i++;
  }
  APP_PRINTF("=============================================================\r\n");
#endif
}

ds_cli_t ds_cli_ins;
ds_cli_handle_t cli_handle = &ds_cli_ins;

void cli_cmd_init()
{
  DS_app_log_info("cli_cmd_init\r\n");
  ds_cli_ins.command_table = ds_cli_default_command_table;
}

void DS_cli_cmd_process(void)
{
    uint8_t *data=NULL;

    while ( bufferIsEmpty(&debug_RXBuff) != true ) {
        data = bufferRemove( &debug_RXBuff );
        ds_cli_ins.input_buffer[ds_cli_ins.input_size ++] = data[0];
        if(ds_cli_ins.input_size >= DS_CLI_INPUT_BUFFER_SIZE) {
            DS_app_log_error("Urx = %d \r\n", ds_cli_ins.input_size);
            ds_cli_ins.input_size = 0;
            memset(ds_cli_ins.input_buffer, 0, DS_CLI_INPUT_BUFFER_SIZE);
        }
    }
    if( strstr(ds_cli_ins.input_buffer, "\r") != NULL ) {
        //printf(">> %s \r\n", ds_cli_ins.input_buffer);
        char msg[255] = {0x00};
        int msg_len = 0;
        msg_len = sprintf(msg,">> %s \r\n",ds_cli_ins.input_buffer);
        msg[msg_len] = '\0';
        DS_debugTxbuff((uint8_t *)msg, strlen(msg));

        DS_cli_handle_work(cli_handle);
    }
}

